#include "hserialport.h"
#include "qdebug.h"
#include "MDateTime/MDateTime.h"
#ifdef Q_OS_WIN
    // windows系统 精确延时 1ms
    #include <MMSystem.h>
    #include <Windows.h>
    #pragma comment(lib, "winmm.lib")
#elif defined(Q_OS_LINUX)
    // linux系统 后续用到的时候再补充
#elif defined(Q_OS_MAC)
    // mac系统 后续用到的时候再补充
#endif

HSerialPort::HSerialPort() {
    m_pEnumerator = new QextSerialEnumerator(this);
    m_pEnumerator->setUpNotifications();
    connect(m_pEnumerator, &QextSerialEnumerator::deviceDiscovered, this,
            &HSerialPort::onPortAddedOrRemoved);
    connect(m_pEnumerator, &QextSerialEnumerator::deviceRemoved, this,
            &HSerialPort::onPortAddedOrRemoved);

    // 设置模式为事件驱动模式
    m_pPort = new QextSerialPort(QextSerialPort::EventDriven);


}

void HSerialPort::setup(PortSettings serial_config) {
    m_serialConfig.BaudRate = serial_config.BaudRate;
    m_serialConfig.DataBits = serial_config.DataBits;
    m_serialConfig.StopBits = serial_config.StopBits;
    m_serialConfig.Parity = serial_config.Parity;
    m_serialConfig.FlowControl = serial_config.FlowControl;

    if (m_pPort) {
        if (m_pPort->baudRate() != serial_config.BaudRate) {
            m_pPort->setBaudRate(serial_config.BaudRate);
        }
        if (m_pPort->dataBits() != serial_config.DataBits) {
            m_pPort->setDataBits(serial_config.DataBits);
        }
        if (m_pPort->stopBits() != serial_config.StopBits) {
            m_pPort->setStopBits(serial_config.StopBits);
        }
        if (m_pPort->parity() != serial_config.Parity) {
            m_pPort->setParity(serial_config.Parity);
        }
        if (m_pPort->flowControl() != serial_config.FlowControl) {
            m_pPort->setFlowControl(serial_config.FlowControl);
        }
    }
}

bool HSerialPort::open(QString port) {
    bool bFlag = true;
    if (!m_pPort->isOpen()) {
        m_pPort->setPortName(port);
        bFlag = m_pPort->open(QIODevice::ReadWrite);
    }
    return bFlag;
}

void HSerialPort::close()
{
    if(m_pPort->isOpen()){
        m_pPort->close();
    }
}

int HSerialPort::write(QByteArray &ucDataArray)
{
    if(!m_pPort->isOpen()){
        qDebug() << "请先打开串口……";
        return -1;
    }

    return m_pPort->write(ucDataArray.data());
}

void HSerialPort::onPortAddedOrRemoved() {
    QStringList ports_available;
    foreach (QextPortInfo port, QextSerialEnumerator::getPorts()) {
        ports_available.append(port.portName);
    }
    emit availablePortsChanged(ports_available);
}

void HSerialPort::run()
{
    m_bStopped = true;
    int nAvailable  = 0;
    QByteArray  m_arrBuffer;
    m_arrBuffer.clear();

    while (m_bStopped) // 如果串口被成功初始化并且正确打开，否则就结束。
    {
#ifdef Q_OS_WIN
        // windows系统 精确延时 1ms
        timeBeginPeriod(1);
        Sleep(1);
        timeEndPeriod(1);
#elif defined(Q_OS_LINUX)
        // linux系统 后续用到的时候再补充
        sleep(1)
#elif defined(Q_OS_MAC)
        // mac系统 后续用到的时候再补充
#endif
        qDebug() << "Timer timeout" << MDateTime::currentDateTime();
        nAvailable = m_pPort->bytesAvailable();
        if(nAvailable > 0)
        {
            // m_arrBuffer.resize(nAvailable);

            m_arrBuffer.append(m_pPort->readAll());

            if(m_arrBuffer.size() > 0)
            {
                qDebug() << m_arrBuffer.toHex() << getTimeStamp();
                emit signal_initialData(false,m_arrBuffer, getTimeStamp());

                m_arrBuffer.clear();
            }
        }

    }
    m_bStopped = false;
}

quint64 HSerialPort::getTimeStamp()
{
    if(m_bUseXCLK){
        return XCLK;
    }
    else{
        return MDateTime::currentMSecsSinceEpoch();
    }
}





